﻿/*** FlashFurcInstaller (FFI) Class - FlashFurc Core
 * ---
 * Author: IceDragon <icedragon@quickfox.org>
 * Web:    www.icerealm.org
 * ---
 * 
 * Copyright (c) 2010, IceRealm.org
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   # Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   # Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   # Neither the name of the IceRealm.org nor the names of its contributors
 *     may be used to endorse or promote products derived from this software
 *     without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace FlashFurc
{
    /// <summary>
    /// This structure represents the install settings for the FFI
    /// </summary>
    public struct InstallSettings
    {
        /// <summary>
        /// Where should Furcadia be installed? (full path, INCLUDING the
        /// Furcadia subfolder: @"H:\Furcadia\" rather than @"H:\")
        /// </summary>
        public string InstallTarget;

        /// <summary>
        /// Should the cache data from the current install be copied (if any)?
        /// </summary>
        public bool CopyCacheData;

        /// <summary>
        /// Should the log files be copied over (if any)?
        /// </summary>
        public bool CopyLogs;

        /// <summary>
        /// Should the Furcadia settings be copied over (if any)?
        /// </summary>
        public bool CopySettings;
    }

    /// <summary>
    /// Abstract class for a FlashFurc Installer
    /// </summary>
    public abstract class FlashFurcInstaller
    {
        /// <summary>
        /// Which files should be ignored and not copied over under any
        /// circumstances? Normally, these files have nothing to do with the
        /// portable nature of Furcadia.
        /// 
        /// NOTE: Use lowercase filenames!
        /// </summary>
        public static List<string> IGNORED_FILES = new List<string>(new string[] { "_uninst.exe", "_uninst.hxq" });

        /// <summary>
        /// Which folder name within the portable Furcadia folder should the
        /// additional data be stored in?
        /// </summary>
        public const string DATA_FOLDER = "data";

        /*** Class Functions *************************************************/
        public static void CreateLocaldir(DirectoryInfo di)
        {
            StreamWriter sw = new StreamWriter(di.FullName + Path.DirectorySeparatorChar + "localdir.ini", false);
            sw.Write(DATA_FOLDER + Path.DirectorySeparatorChar);
            sw.Close();
        }

        /*** Members *********************************************************/
        public bool Available { get; protected set; }
        public string Status { get; protected set; }

        public InstallSettings Settings
        {
            get { return this.settings; }
            set
            {
                lock (this)
                {
                    // Don't set these if the object is busy!
                    if (isBusy)
                        throw new BusyException();
                    else
                        this.settings = value;
                }
            }
        }

        /* Counters */
        public int TotalFiles { get; protected set; }
        public ulong TotalSize { get; protected set; }
        public int CurrentFile { get; protected set; }
        public ulong CurrentSize { get; protected set; }

        /* Lists */
        public List<FileInfo> CharacterFiles = new List<FileInfo>();

        /*** Constructors ***************************************************/
        public FlashFurcInstaller()
        {
            TotalFiles = 0;
            TotalSize = 0;
            CurrentFile = 0;
            CurrentSize = 0;

            Status = "Ready";
            Available = false;
        }
        public FlashFurcInstaller(InstallSettings iset) : this()
        {
            Settings = iset;
        }

        /*** Methods ********************************************************/
        public abstract void Run();

        #region Private Stuff
        protected bool isBusy = false;
        protected bool busy
        {
            get { return isBusy; }
            set
            {
                lock (this)
                {
                    // If they're trying to set the BUSY mode and the system
                    // is already busy, throw an exception.
                    if (isBusy && value)
                        throw new BusyException();
                    else
                        isBusy = value;
                }
            }
        }

        protected InstallSettings settings;
        #endregion
    }
}
